/*
============================================================================
Name        : CVersificatorAppUi from VersificatorAppui.cpp
Author      : 
Version     :
Copyright   : Your copyright notice
Description : CVersificatorAppUi implementation
============================================================================
*/

// INCLUDE FILES
#include "VersificatorAppui.h"
#include "VersificatorView.h"
#include "VersificatorContainer.h"

#include <Versificator.rsg>
#include "Versificator.hrh"

#include <eikenv.h>
#include <avkon.hrh>
#include <coecntrl.h>
#include <eikmenup.h>

#include <eikspane.h>		//CEikStatusPaneBase
#include <aknnavi.h>		//CAknNavigationControlContainer
#include <aknnavide.h>		//CAknNavigationDecorator
#include <avkon.rsg>		//R_AVKON_NAVI_PANE_VOLUME_INDICATOR
#include <avkon.hrh>		//EEikStatusPaneUidNavi

#include "PluginInterface.h"
#include "PlayerPlugin.h"
#include "PluginUtility.h"
#include "Connection.h"


// ================= MEMBER FUNCTIONS =======================
//
// ----------------------------------------------------------
// CVersificatorAppUi::ConstructL()
// 
// ----------------------------------------------------------
//
void CVersificatorAppUi::ConstructL()
{
	BaseConstructL();

	//Volume tab
	iNaviPane = static_cast<CAknNavigationControlContainer*>( CEikStatusPaneBase::Current()->ControlL(TUid::Uid( EEikStatusPaneUidNavi)));
    iVolumeNavi = iNaviPane->CreateVolumeIndicatorL(R_AVKON_NAVI_PANE_VOLUME_INDICATOR);
	//iVolumeNavi->SetObserver(this); //??? MCoeObserver
	iNaviPane->PushL(*iVolumeNavi);

	//Create view
	iAppView = new (ELeave) CVersificatorView;
	CleanupStack::PushL(iAppView);
	iAppView->ConstructL();
	AddViewL(iAppView);      // transfer ownership to CAknViewAppUi
	CleanupStack::Pop();    // view

	//Search for plugins
	GetPlugins();

	//Create player plugin
	iPlayerPlugin = CPlayerPlugin::NewL();
	iPlayerPlugin->SetContainer(iAppView->iContainer);

	//Add plugins containers
	for (TInt i = 0; i < iPlugins.Count(); ++i)
	{
		iPlugins[i]->SetContainer(iAppView->iContainer);
	}

	//By default, volume 4
	iVolume = 4;

	//By default, set player
	//SetPluginL(iPlayerPlugin);
	if (iPlugins.Count() == 0)
	{
		SetPluginL(iPlayerPlugin);
	}
	else
	{
		SetPluginL(iPlugins[iPlugins.Count()-1]);
	}

	//Set view as default view
	SetDefaultViewL(*iAppView);
}

// ----------------------------------------------------
// CVersificatorAppUi::~CVersificatorAppUi()
// Destructor
// Frees reserved resources
// ----------------------------------------------------
//
CVersificatorAppUi::~CVersificatorAppUi()
{
	//Volume control
	DELETE(iVolumeNavi);

	//Remove player plugin
	DELETE(iPlayerPlugin);

	//Remove plugin reference
	iCurrentPlugin = NULL;

	//Destroy connection object
	CConnection::Destroy();

	//properly destroy the plugin array
	iPlugins.ResetAndDestroy();
	REComSession::FinalClose();
}

// ------------------------------------------------------------------------------
// CVersificatorAppUi::DynInitMenuPaneL(TInt aResourceId,CEikMenuPane* aMenuPane)
//  This function is called by the EIKON framework just before it displays
//  a menu pane. Its default implementation is empty, and by overriding it,
//  the application can set the state of menu items dynamically according
//  to the state of application data.
// ------------------------------------------------------------------------------
//
void CVersificatorAppUi::DynInitMenuPaneL(TInt aResourceId, CEikMenuPane* aMenuPane)
{
	if ( aResourceId == R_VERSIFICATOR_PLUGINS_MENU )
	{
		// Add any available plugins to the menu options
		CEikMenuPaneItem::SData sd;
		for ( TInt i = 0; i < iPlugins.Count(); i++ )
		{
			sd.iCommandId = iPlugins[i]->GetMenuCommand();
			sd.iText.Copy(iPlugins[i]->GetMenuText());
			sd.iFlags = 0;
			sd.iCascadeId = 0;
			TRAPD(err, aMenuPane->AddMenuItemL(sd));
		}
	}
	else if (aResourceId == R_VERSIFICATOR_EXTRA_MENU)
	{
		iCurrentPlugin->AddExtraMenu(aMenuPane);

		//Play
		AddMenuItem(EVersificatorCmdPlay, _L("Play"), aMenuPane, !iCurrentPlugin->IsReadyToPlay());

		//Pause
		AddMenuItem(EVersificatorCmdPause, _L("Pause"), aMenuPane, !iCurrentPlugin->IsReadyToPause());

		//Stop
		AddMenuItem(EVersificatorCmdStop, _L("Stop"), aMenuPane, !iCurrentPlugin->IsReadyToStop());
	}
}

void CVersificatorAppUi::GetPlugins()
{
	// Discover installed plugins
	RImplInfoPtrArray infoArray;

	TRAPD(err, {
		CPluginInterface::ListAllImplementationsL(infoArray);
	});

	for (TInt i = 0; i < infoArray.Count(); i++)
	{
		// Slice off first sub-section in the data section
		TPtrC8 type = infoArray[i]->DataType();

		// Create object of type and call its function
		CPluginInterface::TPluginInterfaceInitParams initParams;
		iPlugins.Append(CPluginInterface::NewL(type, initParams)); //OK!

	}
	infoArray.ResetAndDestroy();
}

void CVersificatorAppUi::SetPluginL(CPluginInterface* aPlugin)
{
	if (iCurrentPlugin == aPlugin) return;

	//Deactivate current plugin
	if (iCurrentPlugin) iCurrentPlugin->Deactivate();

	//Set current plugin
	iCurrentPlugin = aPlugin;

	//Synchronize ui volume and plugin
	SetVolume(iVolume);

	//Activate plugin
	iCurrentPlugin->Activate();

	//Prepare container
	iAppView->iContainer->SetColors(
		iCurrentPlugin->BackBorderColor(), iCurrentPlugin->BackShadowColor(), iCurrentPlugin->BackColor(),
		iCurrentPlugin->InsideBorderColor(), iCurrentPlugin->InsideColor(), iCurrentPlugin->ForeColor()
	);
	iAppView->iContainer->SetTitle(aPlugin->GetMenuText());

	//Repaint
	iAppView->iContainer->Repaint();
}

void CVersificatorAppUi::HandleCommandL(TInt aCommand)
{
	switch ( aCommand )
	{
	case EVersificatorCmdPlayer:
		SetPluginL(iPlayerPlugin);
		break;

	case EEikCmdExit:
	case EAknSoftkeyExit:
		Exit();
		break;

	case EVersificatorCmdPlay:
		//Play
		iCurrentPlugin->PlayL();
		break;

	case EVersificatorCmdPause:
		iCurrentPlugin->PauseL();
		break;

	case EVersificatorCmdStop:
		iCurrentPlugin->StopL();
		break;

	default:

		TInt i = 0;
		for ( i = 0; i < iPlugins.Count(); ++i )
		{
			if ( iPlugins[i]->GetMenuCommand() == aCommand )
			{
				// Set the adapter to the found plugin
				SetPluginL(iPlugins[i]);
				break;
			}
		}

		// If the command didn't match any plugins, this must be a command for the plugin
		if ( i >= iPlugins.Count() )
		{
			// try to route the command.
			iCurrentPlugin->HandleCommandL(aCommand);
		}
		break;
	}
}

void CVersificatorAppUi::AddMenuItem(TInt aCommandId, TPtrC aText, CEikMenuPane* aMenuPane, TBool aDimmed)
{
	CEikMenuPaneItem::SData sd;
	sd.iCommandId = aCommandId;
	sd.iText.Copy(aText);
	sd.iFlags = 0;
	sd.iCascadeId = 0;
	TRAPD(err, aMenuPane->AddMenuItemL(sd));
	aMenuPane->SetItemDimmed(aCommandId, aDimmed);
}

TKeyResponse CVersificatorAppUi::HandleKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
{
    switch (aKeyEvent.iCode)
	{
		case EKeyLeftArrow:
		{
			SetVolume(--iVolume);
			return EKeyWasConsumed;
		}
		case EKeyRightArrow:
		{
			SetVolume(++iVolume);
			return EKeyWasConsumed;
		}
		default:
			return iCurrentPlugin->HandleKeyEventL(aKeyEvent, aType);
	}
	return EKeyWasNotConsumed;
}

void CVersificatorAppUi::HandleForegroundEventL(TBool aForeground)
{
	//Call base class method
	CAknAppUi::HandleForegroundEventL(aForeground);

	//Check if there is any plugin running
	if (!iCurrentPlugin) return;

	if(aForeground)
	{
		//We have gained the focus. Activate current plugin
		//iCurrentPlugin->Activate();
	}
	else
	{
		//We have lost the focus. Deactivate current plugin
		//iCurrentPlugin->Deactivate();
	}
}
void CVersificatorAppUi::SetVolume(TInt aVolume)
{
	if (aVolume < 0) aVolume = 0;
	else if (aVolume > 10) aVolume = 10;

	//Set volume in control
	CAknVolumeControl* volumeControl = static_cast<CAknVolumeControl*>(iVolumeNavi->DecoratedControl());
	volumeControl->SetValue(aVolume < 1 ? 1 : aVolume);
	
	//Set volume to plugin
	iCurrentPlugin->SetVolume(aVolume);

	//Save volume
	iVolume = aVolume;
}
